package com.example.service.impl;

import com.example.common.Result;
import com.example.common.PageResult;
import com.example.dto.AppointmentDTO;
import com.example.entity.*;
import com.example.mapper.AppointmentMapper;
import com.example.mapper.HaircutPackageMapper;
import com.example.mapper.RoleMapper;
import com.example.mapper.UserMapper;
import com.example.mapper.UserRoleMapper;
import com.example.mapper.WorkScheduleMapper;
import com.example.mapper.WorkScheduleDateMapper;
import com.example.service.AppointmentService;
import com.example.service.ConsumptionRecordService;
import com.example.service.UserBalanceService;
import com.example.util.UserContextUtil;
import com.example.vo.AppointmentVO;
import com.example.vo.StoreManagerScheduleVO;
import com.example.vo.TimeSlotAvailabilityVO;
import com.example.vo.WorkScheduleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 预约服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AppointmentServiceImpl implements AppointmentService {
    
    private final AppointmentMapper appointmentMapper;
    private final WorkScheduleMapper workScheduleMapper;
    private final WorkScheduleDateMapper workScheduleDateMapper;
    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleMapper roleMapper;
    private final UserContextUtil userContextUtil;
    private final HaircutPackageMapper haircutPackageMapper;
    private final UserBalanceService userBalanceService;
    private final ConsumptionRecordService consumptionRecordService;
    
    // 状态名称映射
    private static final Map<Integer, String> STATUS_NAMES = Map.of(
        0, "待确认", 1, "已确认", 2, "已完成", 3, "已取消"
    );
    
    // 星期几名称映射
    private static final Map<Integer, String> DAY_OF_WEEK_NAMES = Map.of(
        1, "周一", 2, "周二", 3, "周三", 4, "周四", 
        5, "周五", 6, "周六", 7, "周日"
    );
    
    @Override
    @Transactional
    public Result<Void> createAppointment(AppointmentDTO appointmentDTO) {
        try {
            // 获取当前用户ID
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }
            
            // 参数校验
            Result<Void> validationResult = validateAppointmentDTO(appointmentDTO);
            if (!validationResult.isSuccess()) {
                return validationResult;
            }
            
            // 检查预约日期是否为今天或未来
            if (appointmentDTO.getAppointmentDate().isBefore(LocalDate.now())) {
                return Result.error("不能预约过去的日期");
            }
            
            // 检查店长在该时间段是否有排班（优先检查特定日期排班，再检查周排班）
            Integer maxAppointments = null;
            
            // 首先检查特定日期排班
            WorkScheduleDate dateSchedule = workScheduleDateMapper.selectByStoreManagerIdAndDateTime(
                appointmentDTO.getStoreManagerId(), 
                appointmentDTO.getAppointmentDate(), 
                appointmentDTO.getAppointmentHour()
            );
            
            if (dateSchedule != null && dateSchedule.getStatus() == 1) {
                // 有特定日期排班且启用
                maxAppointments = dateSchedule.getMaxAppointments();
            } else {
                // 没有特定日期排班，检查周排班
                int dayOfWeek = appointmentDTO.getAppointmentDate().getDayOfWeek().getValue();
                WorkSchedule weeklySchedule = workScheduleMapper.selectByStoreManagerIdAndTime(
                    appointmentDTO.getStoreManagerId(), dayOfWeek, appointmentDTO.getAppointmentHour()
                );
                
                if (weeklySchedule != null && weeklySchedule.getStatus() == 1) {
                    maxAppointments = weeklySchedule.getMaxAppointments();
                }
            }
            
            if (maxAppointments == null) {
                return Result.error("该时间段店长没有排班");
            }
            
            // 检查该时间段预约数量是否已满
            int currentAppointments = appointmentMapper.countByStoreManagerAndDateTime(
                appointmentDTO.getStoreManagerId(),
                appointmentDTO.getAppointmentDate(),
                appointmentDTO.getAppointmentHour()
            );
            if (currentAppointments >= maxAppointments) {
                return Result.error("该时间段预约已满");
            }
            
            // 检查用户是否已在该时间段预约
            Appointment existingAppointment = appointmentMapper.selectByUserAndDateTime(
                userId,
                appointmentDTO.getStoreManagerId(),
                appointmentDTO.getAppointmentDate(),
                appointmentDTO.getAppointmentHour()
            );
            if (existingAppointment != null && existingAppointment.getStatus() == 1) {
                return Result.error("您已在该时间段预约");
            }
            
            // 获取套餐信息
            HaircutPackage haircutPackage = null;
            if (appointmentDTO.getPackageId() != null) {
                haircutPackage = haircutPackageMapper.selectById(appointmentDTO.getPackageId());
                if (haircutPackage == null || haircutPackage.getStatus() != 1) {
                    return Result.error("选择的套餐不存在或已禁用");
                }
            }
            
            // 创建预约记录
            Appointment appointment = new Appointment();
            appointment.setUserId(userId);
            appointment.setStoreManagerId(appointmentDTO.getStoreManagerId());
            appointment.setAppointmentDate(appointmentDTO.getAppointmentDate());
            appointment.setAppointmentHour(appointmentDTO.getAppointmentHour());
            appointment.setStatus(0); // 待确认
            
            // 设置套餐信息
            if (haircutPackage != null) {
                appointment.setPackageId(haircutPackage.getId());
                appointment.setPackageName(haircutPackage.getPackageName());
                appointment.setPackagePrice(haircutPackage.getPackagePrice());
            }
            appointment.setPaymentStatus(0); // 未支付
            
            appointment.setRemark(appointmentDTO.getRemark());
            appointment.setCreateTime(LocalDateTime.now());
            appointment.setUpdateTime(LocalDateTime.now());
            appointment.setDeleted(0);
            
            int result = appointmentMapper.insert(appointment);
            if (result > 0) {
                return Result.success();
            } else {
                return Result.error("创建预约失败");
            }
        } catch (Exception e) {
            log.error("创建预约失败", e);
            return Result.error("创建预约失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> cancelAppointment(Long appointmentId) {
        try {
            // 获取当前用户ID
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }

            // 查询预约记录
            Appointment appointment = appointmentMapper.selectById(appointmentId);
            if (appointment == null || appointment.getDeleted() == 1) {
                return Result.error("预约记录不存在");
            }

            // 检查权限：用户只能取消自己的预约，店长可以取消分配给自己的预约，管理员可以取消任何预约
            boolean isAdmin = isUserAdmin(userId);
            boolean isStoreManager = isUserStoreManager(userId);
            boolean canCancel = false;

            if (isAdmin) {
                // 管理员可以取消任何预约
                canCancel = true;
            } else if (isStoreManager && appointment.getStoreManagerId() != null && appointment.getStoreManagerId().equals(userId)) {
                // 店长可以取消分配给自己的预约
                canCancel = true;
            } else if (appointment.getUserId() != null && appointment.getUserId().equals(userId)) {
                // 用户可以取消自己的预约
                canCancel = true;
            }

            if (!canCancel) {
                log.warn("用户{}尝试取消预约{}失败，权限不足。预约用户ID：{}，店长ID：{}，当前用户是否管理员：{}，是否店长：{}",
                    userId, appointmentId, appointment.getUserId(), appointment.getStoreManagerId(), isAdmin, isStoreManager);
                return Result.error("无权限取消此预约");
            }
            
            // 检查预约状态
            if (appointment.getStatus() != 0 && appointment.getStatus() != 1) {
                return Result.error("只能取消待确认或已确认状态的预约");
            }

            // 店长和管理员可以随时取消预约，普通用户需要检查时间限制
            if (!isAdmin && !isStoreManager) {
                // 检查是否可以取消（预约时间前1小时才能取消）
                LocalDateTime appointmentDateTime = appointment.getAppointmentDate().atTime(appointment.getAppointmentHour(), 0);
                if (LocalDateTime.now().isAfter(appointmentDateTime.minusHours(1))) {
                    return Result.error("预约开始前1小时内不能取消");
                }
            }
            
            // 更新预约状态为已取消
            Appointment updateAppointment = new Appointment();
            updateAppointment.setId(appointmentId);
            updateAppointment.setStatus(3); // 已取消
            updateAppointment.setUpdateTime(LocalDateTime.now());
            
            int result = appointmentMapper.updateById(updateAppointment);
            if (result > 0) {
                return Result.success();
            } else {
                return Result.error("取消预约失败");
            }
        } catch (Exception e) {
            log.error("取消预约失败", e);
            return Result.error("取消预约失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<AppointmentVO> getAppointmentById(Long id) {
        try {
            // 获取当前用户ID
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }
            
            Appointment appointment = appointmentMapper.selectById(id);
            if (appointment == null || appointment.getDeleted() == 1) {
                return Result.error("预约记录不存在");
            }
            
            // 检查权限（用户只能查看自己的预约，店长可以查看自己的预约）
            if (!appointment.getUserId().equals(userId) && !appointment.getStoreManagerId().equals(userId)) {
                return Result.error("无权限查看此预约");
            }
            
            AppointmentVO vo = convertToVO(appointment);
            return Result.success(vo);
        } catch (Exception e) {
            log.error("查询预约详情失败", e);
            return Result.error("查询预约详情失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<AppointmentVO>> getMyAppointments() {
        try {
            // 获取当前用户ID
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }
            
            List<Appointment> appointments = appointmentMapper.selectByUserId(userId);
            List<AppointmentVO> vos = appointments.stream()
                .map(this::convertToVO)
                .sorted(Comparator.comparing(AppointmentVO::getAppointmentDate).reversed()
                    .thenComparing(AppointmentVO::getAppointmentHour).reversed())
                .collect(Collectors.toList());
            
            return Result.success(vos);
        } catch (Exception e) {
            log.error("查询我的预约列表失败", e);
            return Result.error("查询我的预约列表失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<AppointmentVO>> getStoreManagerAppointments() {
        try {
            // 获取当前用户ID（店长ID）
            Long storeManagerId = userContextUtil.getCurrentUserId();
            if (storeManagerId == null) {
                return Result.error("用户未登录");
            }

            List<Appointment> appointments = appointmentMapper.selectByStoreManagerId(storeManagerId);
            List<AppointmentVO> vos = appointments.stream()
                .map(this::convertToVO)
                .sorted(Comparator.comparing(AppointmentVO::getAppointmentDate).reversed()
                    .thenComparing(AppointmentVO::getAppointmentHour).reversed())
                .collect(Collectors.toList());

            return Result.success(vos);
        } catch (Exception e) {
            log.error("查询店长预约列表失败", e);
            return Result.error("查询店长预约列表失败：" + e.getMessage());
        }
    }

    @Override
    public Result<List<AppointmentVO>> getStoreManagerAppointments(String startDate, String endDate,
                                                                  Integer status, String serviceType) {
        try {
            // 获取当前用户ID（店长ID）
            Long storeManagerId = userContextUtil.getCurrentUserId();
            if (storeManagerId == null) {
                return Result.error("用户未登录");
            }

            List<AppointmentVO> appointments = appointmentMapper.selectStoreManagerAppointments(
                storeManagerId, startDate, endDate, status, serviceType
            );

            // 按预约日期和时间倒序排列
            appointments = appointments.stream()
                .sorted(Comparator.comparing(AppointmentVO::getAppointmentDate).reversed()
                    .thenComparing(AppointmentVO::getAppointmentHour).reversed())
                .collect(Collectors.toList());

            return Result.success(appointments);
        } catch (Exception e) {
            log.error("查询店长预约列表失败", e);
            return Result.error("查询店长预约列表失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<PageResult<AppointmentVO>> getAppointmentPage(int page, int size, 
                                                               Long userId, Long storeManagerId, 
                                                               Integer status) {
        try {
            int offset = (page - 1) * size;
            
            List<Appointment> appointments = appointmentMapper.selectPage(
                offset, size, userId, storeManagerId, status, null, null
            );
            
            long total = appointmentMapper.selectCount(
                userId, storeManagerId, status, null, null
            );
            
            List<AppointmentVO> vos = appointments.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
            
            PageResult<AppointmentVO> pageResult = new PageResult<>(page, size, total, vos);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("分页查询预约记录失败", e);
            return Result.error("分页查询预约记录失败：" + e.getMessage());
        }
    }

    @Override
    public Result<PageResult<AppointmentVO>> getAdminAppointmentPage(int page, int size,
                                                                   String username, String storeManagerName,
                                                                   Integer status, String packageName,
                                                                   String startDate, String endDate) {
        try {
            // 设置分页
            com.github.pagehelper.PageHelper.startPage(page, size);
            
            // 查询数据
            List<AppointmentVO> appointments = appointmentMapper.selectAdminAppointmentPage(
                username, storeManagerName, status, packageName, startDate, endDate
            );
            
            // 查询总数
            long total = appointmentMapper.selectAdminAppointmentCount(
                username, storeManagerName, status, packageName, startDate, endDate
            );
            
            PageResult<AppointmentVO> pageResult = new PageResult<>(page, size, total, appointments);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("管理员分页查询预约记录失败", e);
            return Result.error("管理员分页查询预约记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<StoreManagerScheduleVO>> getAllStoreManagerSchedules() {
        try {
            // 获取所有启用的排班记录
            List<WorkSchedule> allSchedules = workScheduleMapper.selectAllActiveSchedules();
            
            // 按店长ID分组
            Map<Long, List<WorkSchedule>> schedulesByManager = allSchedules.stream()
                .collect(Collectors.groupingBy(WorkSchedule::getStoreManagerId));
            
            // 获取所有店长信息
            List<Long> storeManagerIds = new ArrayList<>(schedulesByManager.keySet());
            Map<Long, User> storeManagerMap = new HashMap<>();
            
            if (!storeManagerIds.isEmpty()) {
                List<User> storeManagers = userMapper.selectByIds(storeManagerIds);
                storeManagerMap = storeManagers.stream()
                    .collect(Collectors.toMap(User::getId, user -> user));
            }
            
            // 构建结果
            List<StoreManagerScheduleVO> result = new ArrayList<>();
            for (Map.Entry<Long, List<WorkSchedule>> entry : schedulesByManager.entrySet()) {
                Long storeManagerId = entry.getKey();
                List<WorkSchedule> schedules = entry.getValue();
                User storeManager = storeManagerMap.get(storeManagerId);
                
                if (storeManager != null) {
                    StoreManagerScheduleVO vo = new StoreManagerScheduleVO();
                    vo.setStoreManagerId(storeManagerId);
                    vo.setStoreManagerName(storeManager.getNickname() != null ? storeManager.getNickname() : storeManager.getUsername());
                    vo.setAvatar(storeManager.getAvatar()); // 设置店长头像
                    vo.setDescription("专业理发师"); // 可以从用户表的其他字段获取
                    vo.setTotalSchedules(schedules.size());
                    
                    // 构建周排班表
                    vo.setWeeklySchedule(buildWeeklySchedule(schedules));
                    
                    result.add(vo);
                }
            }
            
            // 按店长名称排序
            result.sort(Comparator.comparing(StoreManagerScheduleVO::getStoreManagerName));
            
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取所有店长排班时间表失败", e);
            return Result.error("获取所有店长排班时间表失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<StoreManagerScheduleVO> getStoreManagerSchedule(Long storeManagerId) {
        try {
            // 获取店长信息
            User storeManager = userMapper.selectById(storeManagerId);
            if (storeManager == null) {
                return Result.error("店长不存在");
            }
            
            // 获取店长的排班记录
            List<WorkSchedule> schedules = workScheduleMapper.selectByStoreManagerId(storeManagerId);
            
            StoreManagerScheduleVO vo = new StoreManagerScheduleVO();
            vo.setStoreManagerId(storeManagerId);
            vo.setStoreManagerName(storeManager.getNickname() != null ? storeManager.getNickname() : storeManager.getUsername());
            vo.setAvatar(storeManager.getAvatar()); // 设置店长头像
            vo.setDescription("专业理发师");
            vo.setTotalSchedules(schedules.size());
            vo.setWeeklySchedule(buildWeeklySchedule(schedules));
            
            return Result.success(vo);
        } catch (Exception e) {
            log.error("获取店长排班时间表失败", e);
            return Result.error("获取店长排班时间表失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> confirmAppointment(Long appointmentId) {
        try {
            // 获取当前用户ID（管理员或店长ID）
            Long currentUserId = userContextUtil.getCurrentUserId();
            if (currentUserId == null) {
                return Result.error("用户未登录");
            }
            
            // 查询预约记录
            Appointment appointment = appointmentMapper.selectById(appointmentId);
            if (appointment == null || appointment.getDeleted() == 1) {
                return Result.error("预约记录不存在");
            }
            
            // 检查预约状态
            if (appointment.getStatus() != 0) {
                return Result.error("只能确认待确认状态的预约");
            }
            
            // 如果有套餐价格，需要用户支付
            if (appointment.getPackagePrice() != null && appointment.getPackagePrice().compareTo(java.math.BigDecimal.ZERO) > 0) {
                // 检查用户余额是否充足
                Result<Boolean> balanceCheckResult = userBalanceService.checkBalance(appointment.getUserId(), appointment.getPackagePrice());
                if (!balanceCheckResult.isSuccess() || !balanceCheckResult.getData()) {
                    return Result.error("用户余额不足，请先充值");
                }
                
                // 扣除用户余额
                Result<Void> deductResult = userBalanceService.updateBalanceAndTotalConsume(appointment.getUserId(), appointment.getPackagePrice());
                if (!deductResult.isSuccess()) {
                    return Result.error("扣费失败：" + deductResult.getMessage());
                }
                
                // 更新预约支付状态
                appointment.setPaymentStatus(1); // 已支付
                
                // 创建消费记录
                Result<Void> consumptionResult = consumptionRecordService.createConsumptionRecord(appointmentId);
                if (!consumptionResult.isSuccess()) {
                    log.error("创建消费记录失败：{}", consumptionResult.getMessage());
                    // 不影响预约确认，只记录日志
                }
            }
            
            // 更新预约状态为已确认
            Appointment updateAppointment = new Appointment();
            updateAppointment.setId(appointmentId);
            updateAppointment.setStatus(1); // 已确认
            if (appointment.getPaymentStatus() != null) {
                updateAppointment.setPaymentStatus(appointment.getPaymentStatus());
            }
            updateAppointment.setUpdateTime(LocalDateTime.now());
            
            int result = appointmentMapper.updateById(updateAppointment);
            if (result > 0) {
                return Result.success();
            } else {
                return Result.error("确认预约失败");
            }
        } catch (Exception e) {
            log.error("确认预约失败", e);
            return Result.error("确认预约失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> completeAppointment(Long appointmentId) {
        try {
            // 获取当前用户ID
            Long currentUserId = userContextUtil.getCurrentUserId();
            if (currentUserId == null) {
                return Result.error("用户未登录");
            }

            // 查询预约记录
            Appointment appointment = appointmentMapper.selectById(appointmentId);
            if (appointment == null || appointment.getDeleted() == 1) {
                return Result.error("预约记录不存在");
            }

            // 检查权限：店长只能操作自己的预约，管理员可以操作所有预约
            boolean isAdmin = isUserAdmin(currentUserId);
            if (!isAdmin && !appointment.getStoreManagerId().equals(currentUserId)) {
                return Result.error("无权限操作此预约");
            }

            // 检查预约状态
            if (appointment.getStatus() != 1) {
                return Result.error("只能完成已确认状态的预约");
            }
            
            // 更新预约状态为已完成
            Appointment updateAppointment = new Appointment();
            updateAppointment.setId(appointmentId);
            updateAppointment.setStatus(2); // 已完成
            updateAppointment.setUpdateTime(LocalDateTime.now());
            
            int result = appointmentMapper.updateById(updateAppointment);
            if (result > 0) {
                return Result.success();
            } else {
                return Result.error("完成预约失败");
            }
        } catch (Exception e) {
            log.error("完成预约失败", e);
            return Result.error("完成预约失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<Integer>> getStoreManagerAvailableHours(Long storeManagerId, LocalDate appointmentDate) {
        try {
            if (storeManagerId == null) {
                return Result.error("店长ID不能为空");
            }
            
            if (appointmentDate == null) {
                return Result.error("预约日期不能为空");
            }
            
            // 检查预约日期是否为今天或未来
            if (appointmentDate.isBefore(LocalDate.now())) {
                return Result.error("不能预约过去的日期");
            }
            
            List<Integer> availableHours = new ArrayList<>();
            
            // 首先检查特定日期排班
            List<WorkScheduleDate> dateSchedules = workScheduleDateMapper.selectByStoreManagerIdAndDate(storeManagerId, appointmentDate);
            
            if (!dateSchedules.isEmpty()) {
                // 有特定日期排班，使用特定日期排班
                for (WorkScheduleDate schedule : dateSchedules) {
                    if (schedule.getStatus() == 1) { // 启用状态
                        for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                            availableHours.add(hour);
                        }
                    }
                }
            } else {
                // 没有特定日期排班，使用周排班
                int dayOfWeek = appointmentDate.getDayOfWeek().getValue();
                List<WorkSchedule> weeklySchedules = workScheduleMapper.selectByStoreManagerIdAndDayOfWeek(storeManagerId, dayOfWeek);
                
                for (WorkSchedule schedule : weeklySchedules) {
                    if (schedule.getStatus() == 1) { // 启用状态
                        for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                            availableHours.add(hour);
                        }
                    }
                }
            }
            
            // 去重并排序
            availableHours = availableHours.stream()
                .distinct()
                .sorted()
                .collect(Collectors.toList());
            
            return Result.success(availableHours);
        } catch (Exception e) {
            log.error("获取店长可用时间段失败", e);
            return Result.error("获取店长可用时间段失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<StoreManagerScheduleVO>> getAvailableStoreManagersByDate(LocalDate appointmentDate) {
        try {
            if (appointmentDate == null) {
                return Result.error("预约日期不能为空");
            }
            
            // 检查预约日期是否为今天或未来
            if (appointmentDate.isBefore(LocalDate.now())) {
                return Result.error("不能预约过去的日期");
            }
            
            List<StoreManagerScheduleVO> result = new ArrayList<>();
            
            // 获取该日期的所有特定日期排班
            List<WorkScheduleDate> dateSchedules = workScheduleDateMapper.selectAllActiveDateSchedules()
                .stream()
                .filter(schedule -> schedule.getScheduleDate().equals(appointmentDate))
                .collect(Collectors.toList());
            
            // 按店长ID分组特定日期排班
            Map<Long, List<WorkScheduleDate>> dateSchedulesByManager = dateSchedules.stream()
                .collect(Collectors.groupingBy(WorkScheduleDate::getStoreManagerId));
            
            // 获取该日期对应的星期几的周排班
            int dayOfWeek = appointmentDate.getDayOfWeek().getValue();
            List<WorkSchedule> weeklySchedules = workScheduleMapper.selectAllActiveSchedules()
                .stream()
                .filter(schedule -> schedule.getDayOfWeek() == dayOfWeek)
                .collect(Collectors.toList());
            
            // 按店长ID分组周排班
            Map<Long, List<WorkSchedule>> weeklySchedulesByManager = weeklySchedules.stream()
                .collect(Collectors.groupingBy(WorkSchedule::getStoreManagerId));
            
            // 获取所有有排班的店长ID
            Set<Long> allStoreManagerIds = new HashSet<>();
            allStoreManagerIds.addAll(dateSchedulesByManager.keySet());
            allStoreManagerIds.addAll(weeklySchedulesByManager.keySet());
            
            if (allStoreManagerIds.isEmpty()) {
                return Result.success(new ArrayList<>());
            }
            
            // 获取店长信息
            List<User> storeManagers = userMapper.selectByIds(new ArrayList<>(allStoreManagerIds));
            Map<Long, User> storeManagerMap = storeManagers.stream()
                .collect(Collectors.toMap(User::getId, user -> user));
            
            // 构建结果
            for (Long storeManagerId : allStoreManagerIds) {
                User storeManager = storeManagerMap.get(storeManagerId);
                if (storeManager == null) continue;
                
                List<Integer> availableHours = new ArrayList<>();
                
                // 优先使用特定日期排班
                List<WorkScheduleDate> managerDateSchedules = dateSchedulesByManager.get(storeManagerId);
                if (managerDateSchedules != null && !managerDateSchedules.isEmpty()) {
                    for (WorkScheduleDate schedule : managerDateSchedules) {
                        if (schedule.getStatus() == 1) {
                            for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                                availableHours.add(hour);
                            }
                        }
                    }
                } else {
                    // 使用周排班
                    List<WorkSchedule> managerWeeklySchedules = weeklySchedulesByManager.get(storeManagerId);
                    if (managerWeeklySchedules != null) {
                        for (WorkSchedule schedule : managerWeeklySchedules) {
                            if (schedule.getStatus() == 1) {
                                for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                                    availableHours.add(hour);
                                }
                            }
                        }
                    }
                }
                
                if (!availableHours.isEmpty()) {
                    // 去重并排序
                    availableHours = availableHours.stream()
                        .distinct()
                        .sorted()
                        .collect(Collectors.toList());
                    
                    StoreManagerScheduleVO vo = new StoreManagerScheduleVO();
                    vo.setStoreManagerId(storeManagerId);
                    vo.setStoreManagerName(storeManager.getNickname() != null ? storeManager.getNickname() : storeManager.getUsername());
                    vo.setAvatar(storeManager.getAvatar()); // 设置店长头像
                    vo.setDescription("专业理发师");
                    vo.setTotalSchedules(availableHours.size());
                    
                    // 构建当日可用时间段
                    List<List<WorkScheduleVO>> dailySchedule = new ArrayList<>();
                    for (int i = 0; i < 7; i++) {
                        dailySchedule.add(new ArrayList<>());
                    }
                    
                    // 只填充当前日期对应的星期几
                    List<WorkScheduleVO> daySchedules = new ArrayList<>();
                    for (Integer hour : availableHours) {
                        WorkScheduleVO scheduleVO = new WorkScheduleVO();
                        scheduleVO.setId(0L); // 临时ID
                        scheduleVO.setStoreManagerId(storeManagerId);
                        scheduleVO.setDayOfWeek(dayOfWeek);
                        scheduleVO.setStartHour(hour);
                        scheduleVO.setEndHour(hour + 1);
                        scheduleVO.setTimeRange(hour + ":00-" + (hour + 1) + ":00");
                        scheduleVO.setMaxAppointments(1); // 默认值
                        scheduleVO.setStatus(1);
                        scheduleVO.setStatusName("启用");
                        daySchedules.add(scheduleVO);
                    }
                    dailySchedule.set(dayOfWeek - 1, daySchedules);
                    vo.setWeeklySchedule(dailySchedule);
                    
                    result.add(vo);
                }
            }
            
            // 按店长名称排序
            result.sort(Comparator.comparing(StoreManagerScheduleVO::getStoreManagerName));
            
            return Result.success(result);
        } catch (Exception e) {
            log.error("根据日期获取可用发型师失败", e);
            return Result.error("根据日期获取可用发型师失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Map<String, List<Integer>>> getStoreManagerAvailableDates(Long storeManagerId, int days) {
        try {
            log.info("获取店长可用日期, storeManagerId: {}, days: {}", storeManagerId, days);
            
            if (storeManagerId == null) {
                log.warn("店长ID不能为空");
                return Result.error("店长ID不能为空");
            }
            
            if (days <= 0 || days > 30) {
                days = 7; // 默认查询7天
                log.info("天数参数调整为默认值: {}", days);
            }
            
            // 验证店长是否存在
            User storeManager = userMapper.selectById(storeManagerId);
            if (storeManager == null) {
                log.warn("店长不存在, storeManagerId: {}", storeManagerId);
                return Result.error("店长不存在");
            }
            
            Map<String, List<Integer>> result = new HashMap<>();
            LocalDate startDate = LocalDate.now();
            
            for (int i = 0; i < days; i++) {
                LocalDate date = startDate.plusDays(i);
                String dateStr = date.toString();
                
                List<Integer> availableHours = new ArrayList<>();
                
                try {
                    // 首先检查特定日期排班
                    List<WorkScheduleDate> dateSchedules = workScheduleDateMapper.selectByStoreManagerIdAndDate(storeManagerId, date);
                    log.debug("店长 {} 在 {} 的特定日期排班: {}", storeManagerId, dateStr, dateSchedules.size());
                    
                    if (!dateSchedules.isEmpty()) {
                        // 有特定日期排班
                        for (WorkScheduleDate schedule : dateSchedules) {
                            if (schedule.getStatus() == 1) {
                                for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                                    availableHours.add(hour);
                                }
                            }
                        }
                    } else {
                        // 使用周排班
                        int dayOfWeek = date.getDayOfWeek().getValue();
                        List<WorkSchedule> weeklySchedules = workScheduleMapper.selectByStoreManagerIdAndDayOfWeek(storeManagerId, dayOfWeek);
                        log.debug("店长 {} 在星期 {} 的周排班: {}", storeManagerId, dayOfWeek, weeklySchedules.size());
                        
                        for (WorkSchedule schedule : weeklySchedules) {
                            if (schedule.getStatus() == 1) {
                                for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                                    availableHours.add(hour);
                                }
                            }
                        }
                    }
                    
                    // 去重并排序
                    availableHours = availableHours.stream()
                        .distinct()
                        .sorted()
                        .collect(Collectors.toList());
                    
                    if (!availableHours.isEmpty()) {
                        result.put(dateStr, availableHours);
                        log.debug("店长 {} 在 {} 可用时间段: {}", storeManagerId, dateStr, availableHours);
                    }
                    
                } catch (Exception dateError) {
                    log.error("处理日期 {} 的排班时出错: ", dateStr, dateError);
                    // 继续处理其他日期，不中断整个流程
                }
            }
            
            log.info("店长 {} 可用日期统计: {} 天", storeManagerId, result.size());
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取店长可用日期失败, storeManagerId: {}, days: {}", storeManagerId, days, e);
            return Result.error("获取店长可用日期失败：" + e.getMessage());
        }
    }
    
    /**
     * 参数校验
     */
    private Result<Void> validateAppointmentDTO(AppointmentDTO dto) {
        if (dto.getStoreManagerId() == null) {
            return Result.error("店长ID不能为空");
        }
        
        if (dto.getAppointmentDate() == null) {
            return Result.error("预约日期不能为空");
        }
        
        if (dto.getAppointmentHour() == null || dto.getAppointmentHour() < 8 || dto.getAppointmentHour() > 20) {
            return Result.error("预约时间参数错误，应为8-20");
        }
        
        return Result.success();
    }
    
    /**
     * 转换为VO
     */
    private AppointmentVO convertToVO(Appointment appointment) {
        AppointmentVO vo = new AppointmentVO();
        vo.setId(appointment.getId());
        vo.setUserId(appointment.getUserId());
        vo.setStoreManagerId(appointment.getStoreManagerId());
        vo.setAppointmentDate(appointment.getAppointmentDate());
        vo.setAppointmentHour(appointment.getAppointmentHour());
        vo.setAppointmentTime(appointment.getAppointmentHour() + ":00-" + (appointment.getAppointmentHour() + 1) + ":00");
        vo.setStatus(appointment.getStatus());
        vo.setStatusName(STATUS_NAMES.get(appointment.getStatus()));
        
        // 设置套餐信息
        vo.setPackageId(appointment.getPackageId());
        vo.setPackageName(appointment.getPackageName());
        vo.setPackagePrice(appointment.getPackagePrice());
        
        // 设置支付状态
        vo.setPaymentStatus(appointment.getPaymentStatus());
        
        vo.setRemark(appointment.getRemark());
        vo.setCreateTime(appointment.getCreateTime());
        vo.setUpdateTime(appointment.getUpdateTime());
        
        // 获取用户和店长名称
        try {
            User user = userMapper.selectById(appointment.getUserId());
            if (user != null) {
                vo.setUsername(user.getUsername());
            }
            
            User storeManager = userMapper.selectById(appointment.getStoreManagerId());
            if (storeManager != null) {
                vo.setStoreManagerName(storeManager.getNickname() != null ? storeManager.getNickname() : storeManager.getUsername());
            }
        } catch (Exception e) {
            log.warn("获取用户或店长信息失败", e);
        }
        
        return vo;
    }
    
    /**
     * 构建周排班表
     */
    private List<List<WorkScheduleVO>> buildWeeklySchedule(List<WorkSchedule> schedules) {
        // 按星期几分组
        Map<Integer, List<WorkSchedule>> schedulesByDay = schedules.stream()
            .filter(schedule -> schedule.getStatus() == 1) // 只包含启用的排班
            .collect(Collectors.groupingBy(WorkSchedule::getDayOfWeek));
        
        // 构建周排班表（7天）
        List<List<WorkScheduleVO>> weeklySchedule = new ArrayList<>();
        for (int day = 1; day <= 7; day++) {
            List<WorkSchedule> daySchedules = schedulesByDay.getOrDefault(day, new ArrayList<>());
            List<WorkScheduleVO> dayVOs = daySchedules.stream()
                .map(this::convertWorkScheduleToVO)
                .sorted(Comparator.comparing(WorkScheduleVO::getStartHour))
                .collect(Collectors.toList());
            weeklySchedule.add(dayVOs);
        }
        
        return weeklySchedule;
    }
    
    /**
     * 转换WorkSchedule为VO
     */
    private WorkScheduleVO convertWorkScheduleToVO(WorkSchedule workSchedule) {
        WorkScheduleVO vo = new WorkScheduleVO();
        vo.setId(workSchedule.getId());
        vo.setStoreManagerId(workSchedule.getStoreManagerId());
        vo.setDayOfWeek(workSchedule.getDayOfWeek());
        vo.setDayOfWeekName(DAY_OF_WEEK_NAMES.get(workSchedule.getDayOfWeek()));
        vo.setStartHour(workSchedule.getStartHour());
        vo.setEndHour(workSchedule.getEndHour());
        vo.setTimeRange(workSchedule.getStartHour() + ":00-" + workSchedule.getEndHour() + ":00");
        vo.setMaxAppointments(workSchedule.getMaxAppointments());
        vo.setStatus(workSchedule.getStatus());
        vo.setStatusName(workSchedule.getStatus() == 1 ? "启用" : "禁用");
        vo.setRemark(workSchedule.getRemark());
        vo.setCreateTime(workSchedule.getCreateTime());
        vo.setUpdateTime(workSchedule.getUpdateTime());
        return vo;
    }
    
    @Override
    public Result<List<TimeSlotAvailabilityVO>> getStoreManagerTimeSlotAvailability(Long storeManagerId, LocalDate appointmentDate) {
        try {
            log.info("获取时间段可用性, storeManagerId: {}, appointmentDate: {}", storeManagerId, appointmentDate);
            
            if (storeManagerId == null) {
                log.warn("店长ID不能为空");
                return Result.error("店长ID不能为空");
            }
            
            if (appointmentDate == null) {
                log.warn("预约日期不能为空");
                return Result.error("预约日期不能为空");
            }
            
            // 验证店长是否存在
            User storeManager = userMapper.selectById(storeManagerId);
            if (storeManager == null) {
                log.warn("店长不存在, storeManagerId: {}", storeManagerId);
                return Result.error("店长不存在");
            }
            
            List<TimeSlotAvailabilityVO> result = new ArrayList<>();
            
            // 获取该日期的已预约统计
            List<AppointmentHourCount> bookedCounts = appointmentMapper.countByStoreManagerAndDate(storeManagerId, appointmentDate);
            Map<Integer, Integer> bookedCountMap = bookedCounts.stream()
                .collect(Collectors.toMap(AppointmentHourCount::getAppointmentHour, AppointmentHourCount::getAppointmentCount));
            log.debug("已预约统计: {}", bookedCountMap);
            
            // 首先检查特定日期排班
            List<WorkScheduleDate> dateSchedules = workScheduleDateMapper.selectByStoreManagerIdAndDate(storeManagerId, appointmentDate);
            log.debug("特定日期排班数量: {}", dateSchedules.size());
            
            if (!dateSchedules.isEmpty()) {
                // 有特定日期排班 - 返回完整时段
                for (WorkScheduleDate schedule : dateSchedules) {
                    if (schedule.getStatus() == 1) {
                        try {
                            // 计算该时段的总预约数
                            int totalBooked = 0;
                            for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                                totalBooked += bookedCountMap.getOrDefault(hour, 0);
                            }
                            
                            // 创建完整时段的VO
                            TimeSlotAvailabilityVO slot = new TimeSlotAvailabilityVO();
                            slot.setHour(schedule.getStartHour());
                            slot.setTimeRange(schedule.getStartHour() + ":00-" + schedule.getEndHour() + ":00");
                            slot.setMaxAppointments(schedule.getMaxAppointments());
                            slot.setBookedCount(totalBooked);
                            slot.setRemainingSlots(Math.max(0, schedule.getMaxAppointments() - totalBooked));
                            slot.setAvailable(slot.getRemainingSlots() > 0);
                            result.add(slot);
                            
                            log.debug("特定日期时段: {} - 最大预约: {}, 已预约: {}, 剩余: {}", 
                                    slot.getTimeRange(), slot.getMaxAppointments(), slot.getBookedCount(), slot.getRemainingSlots());
                        } catch (Exception slotError) {
                            log.error("处理特定日期排班时段出错: ", slotError);
                        }
                    }
                }
            } else {
                // 使用周排班 - 返回完整时段
                int dayOfWeek = appointmentDate.getDayOfWeek().getValue();
                List<WorkSchedule> weeklySchedules = workScheduleMapper.selectByStoreManagerIdAndDayOfWeek(storeManagerId, dayOfWeek);
                log.debug("周排班数量: {}", weeklySchedules.size());
                
                for (WorkSchedule schedule : weeklySchedules) {
                    if (schedule.getStatus() == 1) {
                        try {
                            // 计算该时段的总预约数
                            int totalBooked = 0;
                            for (int hour = schedule.getStartHour(); hour < schedule.getEndHour(); hour++) {
                                totalBooked += bookedCountMap.getOrDefault(hour, 0);
                            }
                            
                            // 创建完整时段的VO
                            TimeSlotAvailabilityVO slot = new TimeSlotAvailabilityVO();
                            slot.setHour(schedule.getStartHour());
                            slot.setTimeRange(schedule.getStartHour() + ":00-" + schedule.getEndHour() + ":00");
                            slot.setMaxAppointments(schedule.getMaxAppointments());
                            slot.setBookedCount(totalBooked);
                            slot.setRemainingSlots(Math.max(0, schedule.getMaxAppointments() - totalBooked));
                            slot.setAvailable(slot.getRemainingSlots() > 0);
                            result.add(slot);
                            
                            log.debug("周排班时段: {} - 最大预约: {}, 已预约: {}, 剩余: {}", 
                                    slot.getTimeRange(), slot.getMaxAppointments(), slot.getBookedCount(), slot.getRemainingSlots());
                        } catch (Exception slotError) {
                            log.error("处理周排班时段出错: ", slotError);
                        }
                    }
                }
            }
            
            // 按开始时间排序
            result = result.stream()
                .sorted(Comparator.comparing(TimeSlotAvailabilityVO::getHour))
                .collect(Collectors.toList());
            
            log.info("店长 {} 在 {} 的时间段可用性: {} 个时段", storeManagerId, appointmentDate, result.size());
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取时间段可用性失败, storeManagerId: {}, appointmentDate: {}", storeManagerId, appointmentDate, e);
            return Result.error("获取时间段可用性失败：" + e.getMessage());
        }
    }

    /**
     * 检查用户是否是管理员
     */
    private boolean isUserAdmin(Long userId) {
        try {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            return userRoles.stream()
                    .anyMatch(userRole -> {
                        Role role = roleMapper.selectById(userRole.getRoleId());
                        return role != null && "ADMIN".equals(role.getRoleCode());
                    });
        } catch (Exception e) {
            log.error("检查用户管理员权限失败", e);
            return false;
        }
    }

    /**
     * 检查用户是否是店长
     */
    private boolean isUserStoreManager(Long userId) {
        try {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            return userRoles.stream()
                    .anyMatch(userRole -> {
                        Role role = roleMapper.selectById(userRole.getRoleId());
                        return role != null && "STORE_MANAGER".equals(role.getRoleCode());
                    });
        } catch (Exception e) {
            log.error("检查用户店长权限失败", e);
            return false;
        }
    }
}